#include "singleGame.h"
#include <QTimer>

SingleGame::SingleGame(QWidget *parent)
    : Board{parent}
{
    level = 3;
    firstShow = true;

    m_timeLimitMs = SEARCH_TIME_LIMIT_MS;

    retrackButton.reset(new QPushButton("悔棋", this));
    retrackButton->setGeometry(
        BOARD_LEFT_OFFSET,
        BOARD_TOP_OFFSET + BOARD_ROW_NUM * BOARD_RECT_DIAMETER, 100, 30);
    // 连接按钮的clicked信号到成员函数
    connect(retrackButton.get(), &QPushButton::clicked, this, &SingleGame::onRetrackButtonClicked);
    // 连接子界面的游戏结束信号
    connect(this, &Board::gameOver, this, &SingleGame::buttonDisable);
}

void SingleGame::buttonDisable() {
    // 禁用按钮
    retrackButton->setDisabled(true);
}
void SingleGame::buttonEnable() {
    // 启用按钮
    retrackButton->setDisabled(false);
}


// 玩家设置阵营 1:红  2:黑
void SingleGame::setPlayerSide(int side) {
    // true:上红下黑  false:上黑下红
    // side == 1 玩家选红方 => redTopBlackBottom = false
    // side == 2 玩家选黑方 => redTopBlackBottom = true
    redTopBlackBottom = side == 2;
    initPieces();
}
// 设置AI难度
void SingleGame::setAIDifficulty(Difficulty level) {
    switch (level) {
    case Difficulty::Easy:
        this->level = 2;
        break;
    case Difficulty::Medium:
        this->level = 4;
        break;
    case Difficulty::Hard:
        this->level = 5;
        break;
    default:
        break;
    }
}
// 第一次显示界面时触发电脑走棋
void SingleGame::showEvent(QShowEvent* event) {
    Board::showEvent(event);
    if (firstShow) {
        firstShow = false;
        QTimer::singleShot(500, this, &SingleGame::computerMove);
    }
}
// 重写board的movePiece函数
bool SingleGame::movePiece(int row, int col, int secondId) {
    // redTopBlackBottom为true时, 红方是电脑, 黑方是玩家
    // redTopBlackBottom为false时, 黑方是电脑, 红方是玩家
    // isRedTurn为true时, 红方是执棋方, 黑方是等待方
    // isRedTurn为false时, 黑方是执棋方, 红方是等待方
    const bool isPlayerTurn = (redTopBlackBottom == !isRedTurn);
    // 如果当前不是玩家回合，直接返回
    if (!isPlayerTurn) {
        return false;
    }
    
    // 尝试玩家走棋
    if (!Board::movePiece(row, col, secondId)) {
        return false;
    }
    // 延迟触发电脑走棋（500ms后）
    QTimer::singleShot(500, this, [this]() {
        computerMove();
        });

    return true;
}

void SingleGame::computerMove() {
    if (isGameOver) {
        return;
    }
    const bool isComputerTurn = (redTopBlackBottom == isRedTurn);
    // 确保现在是电脑回合
    if (!isComputerTurn) {
        return;
    }
    buttonDisable();
    // 使用QtConcurrent提交到线程池
    startComputerMove();
}

void SingleGame::getBestStepOfComputerByRecursion() {
    m_bestStep.clear();
    ChessPieces* tempPieces = copyChessPiecesArray(this->pieces);
    minimaxByRecursion(0, redTopBlackBottom, INT_MIN, INT_MAX, tempPieces);
    delete tempPieces;
    tempPieces = nullptr;
}

int SingleGame::minimaxByRecursion(int depth, bool isMaximizingPlayer, int alpha, 
    int beta, ChessPieces pieces[PIECES_NUM]) {
    // 终止条件1：取消请求或超时
    if (m_future.isCanceled() || m_searchTimer.hasExpired(m_timeLimitMs)) {
        return isMaximizingPlayer ? INT_MIN : INT_MAX;
    }
    // 终止条件：达到最大深度或游戏结束
    if (depth == level) {
        return evaluateBoard(pieces);
    }

    // 生成所有可能的走法
    QVector<QSharedPointer<Step>> possibleSteps;
    // redTopBlackBottom == true 电脑为红方
    // redTopBlackBottom == false 电脑为黑方
    generateAllPossibleSteps(possibleSteps, isMaximizingPlayer, pieces);

    // 修正：根据电脑阵营调整实际决策方
    const bool isAITurn = (isMaximizingPlayer == redTopBlackBottom);
    
    if (isAITurn) {
        int maxEval = INT_MIN;
        for (auto& step : possibleSteps) {
            if (m_future.isCanceled() || m_searchTimer.hasExpired(m_timeLimitMs)) {
                break;
            }
            simulateMove(step, pieces);
            int eval = minimaxByRecursion(depth + 1, !isMaximizingPlayer, alpha, beta, pieces);
            undoMove(step, pieces);

            if (eval > maxEval) {
                maxEval = eval;
                // 更新全局最佳步骤（线程安全）
                QMutexLocker locker(&m_bestStepMutex);
                if (eval > m_currentBestEval) {
                    m_currentBestEval = eval;
                    if (depth == 0) {
                        m_bestStep = step;
                        m_currentBestStep = step;
                    }
                }
            }

            alpha = qMax(alpha, eval);
            if (beta <= alpha) break; // Alpha-Beta剪枝
        }
        return maxEval;
    }
    else {
        int minEval = INT_MAX;
        for (auto& step : possibleSteps) {
            if (m_future.isCanceled() || m_searchTimer.hasExpired(m_timeLimitMs)) {
                break;
            }
            simulateMove(step, pieces);
            int eval = minimaxByRecursion(depth + 1, isMaximizingPlayer, alpha, beta, pieces);
            undoMove(step, pieces);

            minEval = qMin(minEval, eval);
            beta = qMin(beta, eval);
            if (beta <= alpha) break; // Alpha-Beta剪枝
        }
        return minEval;
    }
}

int SingleGame::evaluateBoard(ChessPieces pieces[PIECES_NUM]) const {
    int score = 0;

    // 计算红黑双方棋子价值差
    for (int i = 0; i < PIECES_NUM; ++i) {
        if (pieces[i].dead) continue;

        int value = getPieceValue(pieces[i]); 
        if (pieces[i].red == redTopBlackBottom) { // AI方
            score += value;
        }
        else { // 玩家方
            score -= value;
        }

        // 过河兵加分
        if (pieces[i].type == PIECES_TYPE::BING && isCrossedRiver(pieces[i])) {
             score += 50;
        }

        // 车在九宫格位置加分
        if (pieces[i].type == PIECES_TYPE::CHE && isNinePalaceGrid(pieces[i])) {
            score += 50;
        }
    }
    return score;
}

// 悔棋
void SingleGame::onRetrackButtonClicked() {
    bool isRed = !redTopBlackBottom;
    if (isRed) {
        if(redSteps.isEmpty()) {
            return;
        }
        if (!isRedTurn) {
            executeRetrack(true);
            // 切换走棋方
            isRedTurn = !isRedTurn;
        } else {
            executeRetrack(false);
            executeRetrack(true);
        }
    } else {
        if(blackSteps.isEmpty()) {
            return;
        }
        if (isRedTurn) {
            executeRetrack(false);
            // 切换走棋方
            isRedTurn = !isRedTurn;
        } else {
            // 如果当前想悔棋的一方正是执棋的一方, 说明对方已经走了一步
            // 那么需要先回退对方的一步棋, 再回退本方的一步棋
            executeRetrack(false);
            executeRetrack(true);
        }
    }
    update();
}

void SingleGame::cancelComputerMove() {
    if (m_future.isRunning()) {
        // 断开之前的连接
        m_taskWatcher.disconnect(this);

        // 请求取消任务
        m_future.cancel();

        // 等待任务结束（可选，根据需求决定是否阻塞）
        // m_future.waitForFinished();
    }
}

void SingleGame::startComputerMove() {
    // 取消可能正在运行的任务
    cancelComputerMove();

    // 重置状态
    m_timeLimitMs = SEARCH_TIME_LIMIT_MS;
    m_searchTimer.start();
    m_currentBestEval = INT_MIN;
    m_currentBestStep.clear();

    // 启动新任务
    m_future = QtConcurrent::run([this]() {
        getBestStepOfComputerByRecursion();
        // 如果超时，使用当前找到的最佳步骤
        if (m_searchTimer.hasExpired(m_timeLimitMs)) {
            QMutexLocker locker(&m_bestStepMutex);
            if (m_currentBestStep) {
                m_bestStep = m_currentBestStep;
            }
        }
        });

    // 连接完成信号
    connect(&m_taskWatcher, &QFutureWatcher<void>::finished, this, [this]() {
        // 断开连接避免多次触发
        m_taskWatcher.disconnect(this);

        if (!m_bestStep) {
            buttonEnable();
            return;
        }

        // 执行电脑走棋（必须在主线程）
        selectId = m_bestStep->fromId;
        Board::executeMovePiece(m_bestStep->toRow, m_bestStep->toCol, m_bestStep->toId);
        buttonEnable();
        });

    m_taskWatcher.setFuture(m_future);
}

